package com.app.utils.util.image;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;

import com.app.utils.util.ViewSizeUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 操作图片的工具类
 *
 * @author xuxinghai
 */
public class ImageUtils {


    /**
     * 压缩图片至480f x 800f
     * 质量在200kb之内
     *
     * @param imagePath
     * @return Bitmap
     */
    public static Bitmap sampBitmap4(String imagePath) {
        File file = new File(imagePath);
        if (!file.exists()) {
            return null;
        }

        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设成true，不读入内存
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        float hh = 800f;// 这里设置高度为800f
        float ww = 480f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w >= h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);

        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0) {
            be = 1;
        }


//        LogUtils.e("gzq", "w = "+w+" h = "+h+   "    be"+be);

        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(imagePath, newOpts);
        if (bitmap == null) {
            return null;
        }
        return compressImage(bitmap, 200);// 压缩好比例大小后再进行质量压缩
    }

    /**
     * 压缩 bitmap 在size kb之内
     *
     * @param image
     * @return Bitmap
     */
    public static Bitmap compressImage(Bitmap image, int size) {
        if (image == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > size) { // 循环判断如果压缩后图片是否大于200kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            options -= 2;// 每次都减少2
            image.compress(CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }



    /**
     * 压缩图片 大图
     *
     * @param imagePath
     * @return
     */
    public static Bitmap sampBitmap(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 处理图片不加载进内存
        BitmapFactory.decodeFile(imagePath, options);
        int height = options.outHeight;
        int width = options.outWidth;
        // 如果图片的默认高度或者宽大于指定的宽或高 我们就等比例压缩
        int inSampleSize = 1;
        while (true) {
            if (height / inSampleSize > 600 || width / inSampleSize > 600) {
                inSampleSize *= 2;
            } else {
                break;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeFile(imagePath, options);
    }

    /**
     * 压缩图片 中图
     *
     * @param imagePath
     * @return
     */
    public static Bitmap sampBitmap1(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 处理图片不加载进内存
        BitmapFactory.decodeFile(imagePath, options);
        int height = options.outHeight;
        int width = options.outWidth;
        // 如果图片的默认高度或者宽大于指定的宽或高 我们就等比例压缩
        int inSampleSize = 1;
        while (true) {
            if (height / inSampleSize > 400 || width / inSampleSize > 400) {
                inSampleSize *= 2;
            } else {
                break;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeFile(imagePath, options);
    }

    /**
     * 压缩图片 小图
     *
     * @param imagePath
     * @return
     */
    public static Bitmap sampBitmap2(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 处理图片不加载进内存
        BitmapFactory.decodeFile(imagePath, options);
        int height = options.outHeight;
        int width = options.outWidth;
        // 如果图片的默认高度或者宽大于指定的宽或高 我们就等比例压缩
        int inSampleSize = 1;
        while (true) {
            if (height / inSampleSize > 200 || width / inSampleSize > 200) {
                inSampleSize *= 2;
            } else {
                break;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeFile(imagePath, options);
    }


    /***
     * 图片的缩放方法
     *
     * @param file      ：源图片资源
     * @param newWidth  ：缩放后宽度
     * @param newHeight ：缩放后高度
     * @return
     */
    public static Bitmap zoomImage(File file, double newWidth, double newHeight) {
        if (file == null || !file.exists()) {
            return null;
        }

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 处理图片不加载进内存
        BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        int height = options.outHeight;
        int width = options.outWidth;
        // 如果图片的默认高度或者宽大于指定的宽或高 我们就等比例压缩
        int inSampleSize = 1;
        while (true) {
            if (height / inSampleSize > 100 || width / inSampleSize > 100) {
                inSampleSize *= 2;
            } else {
                break;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeFile(file.getAbsolutePath(), options);

    }


    /**
     * 压缩图片 小图
     *
     * @param bitmap
     * @return
     */
    public static Bitmap sampBitmap2(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.PNG, 100, baos);
        InputStream is = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 处理图片不加载进内存
        BitmapFactory.decodeStream(is, null, options);
        int height = options.outHeight;
        int width = options.outWidth;
        // 如果图片的默认高度或者宽大于指定的宽或高 我们就等比例压缩
        int inSampleSize = 1;
        while (true) {
            if (height / inSampleSize > 200 || width / inSampleSize > 200) {
                inSampleSize *= 2;
            } else {
                break;
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeStream(is, null, options);
    }


    /***
     * 图片的缩放方法
     *
     * @param bgimage   ：源图片资源
     * @param newWidth  ：缩放后宽度
     * @param newHeight ：缩放后高度
     * @return
     */
    public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
                                   double newHeight) {
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
//                float f_width_scale = 1;
        float f_width_scale = (float) (width / newWidth);
        float f_height_scale = (float) (height / newHeight);
        float scale = f_height_scale > f_width_scale ? f_height_scale : f_width_scale;
        if (scale < 1) {
            return bgimage;
        }
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        return bitmap;
    }

    /**
     * 保存压缩后的图片
     *
     * @param bmp
     * @param file
     * @return
     */
    public static boolean saveBitmap2file(Bitmap bmp, File file) {
        if (bmp == null || bmp.getRowBytes() * bmp.getHeight() == 0) {
            return false;
        }
        CompressFormat format = CompressFormat.JPEG;
        int quality = 100;
        OutputStream stream = null;
        try {
            stream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        boolean b = false;
        try {
            b = bmp.compress(format, quality, stream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;
    }




    /**
     * Drawable对象转成Bitmap对象
     *
     * @param drawable
     * @return Bitmap
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) {
            return null;
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        // 注意，下面三行代码要用到，否在在View或者surfaceview里的canvas.drawBitmap会看不到图
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * 改变图片的亮度
     *
     * @param imageview
     * @param brightness
     */
    public static void changeLight(ImageView imageview, int brightness) {
        Drawable drawable = imageview.getDrawable();
        Bitmap bitmap = drawableToBitmap(drawable);
        if (bitmap == null) {
            return;
        }
        Canvas canvas = new Canvas(bitmap);
        int color = 0xff424242;
        Paint paint = new Paint();
        Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        // 夜间模式调试图片亮度
        ColorMatrix mLightnessMatrix = new ColorMatrix();// 改变亮度的色值
        mLightnessMatrix.set(new float[]{1, 0, 0, 0, brightness, 0, 1, 0, 0,
                brightness,// 改变亮度
                0, 0, 1, 0, brightness, 0, 0, 0, 1, 0});
        paint.setColorFilter(new ColorMatrixColorFilter(mLightnessMatrix));// 设置颜色变换效果
        canvas.drawRoundRect(rectF, 0, 0, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
    }

    /**
     * 传入bitmap压缩bitmap对象的质量至100kb
     *
     * @param image
     * @return
     */
    public static Bitmap compressBitmapByBitmap(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 90;
        int longs = baos.toByteArray().length;
        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            image.compress(CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
            longs = baos.toByteArray().length;
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    /**
     * 传入file压缩bitmap对象的质量至100kb
     *
     * @param file
     * @return
     */
    public static Bitmap compressBitmapByFile(File file) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(),
                options);
        bitmap = compressBitmapByBitmap(bitmap);// 压缩
        return bitmap;
    }

    /**
     * 传入file文件，得到bitmap按比例改变bitmap的尺寸大小至屏幕大小
     *
     * @param file
     * @return
     */
    public static Bitmap changeBitmapByFile(File file) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 不读进内存
        BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        int outWidth = options.outWidth;
        int outHeight = options.outHeight;
        int screenWidth = ViewSizeUtils.getWidthPixels();
        int screenHeight = ViewSizeUtils.getHeightPixels();
        int inSampleSize = 1;
        if (outHeight > screenHeight || outWidth > screenWidth) {
            int heightRatio = Math.round((float) outHeight
                    / (float) screenHeight);
            int widthRatio = Math.round((float) outWidth / (float) screenWidth);
            inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio;
        }
        options.inSampleSize = inSampleSize;// 设置压缩比例
        options.inJustDecodeBounds = false;
        try {
            return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    //获得圆角图片的方法
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

        if (bitmap == null) {
            return null;
        }
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        if(output == null){
            return null;
        }
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }

    //获得带倒影的图片方法
    public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
        final int reflectionGap = 4;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);

        Bitmap reflectionImage = Bitmap.createBitmap(bitmap,
                0, height / 2, width, height / 2, matrix, false);

        Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmapWithReflection);
        canvas.drawBitmap(bitmap, 0, 0, null);
        Paint deafalutPaint = new Paint();
        canvas.drawRect(0, height, width, height + reflectionGap,
                deafalutPaint);

        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0,
                bitmap.getHeight(), 0, bitmapWithReflection.getHeight()
                + reflectionGap, 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        // Set the Transfer mode to be porter duff and destination in
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        // Draw a rectangle using the paint with our linear gradient
        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
                + reflectionGap, paint);

        return bitmapWithReflection;
    }


    // 将Bitmap转换成InputStream
    public static InputStream bitmap2InputStream(Bitmap bm, int quality) {
        if(bm == null){
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, quality, baos);
        InputStream is = new ByteArrayInputStream(baos.toByteArray());
        return is;
    }


    // Bitmap转换成byte[]
    public static byte[] bitmap2Bytes(Bitmap bm,int quality) {
        if(bm == null){
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, quality, baos);
        return baos.toByteArray();
    }

}
